package com.xiaoyu.shenyou.shenyouv1.task;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.xiaoyu.shenyou.shenyouv1.common.shenyoucode.ToServerCode;
import com.xiaoyu.shenyou.shenyouv1.common.shenyouentity.betconfig.RoundInfo;
import com.xiaoyu.shenyou.shenyouv1.entity.AutoUserEntity;
import com.xiaoyu.shenyou.shenyouv1.mapper.AutoPlayMapper;
import com.xiaoyu.shenyou.shenyouv1.mapper.PredictionMapper;
import com.xiaoyu.shenyou.shenyouv1.websocketclient.autobettingclient.BettingSocketClient;
import com.xiaoyu.shenyou.shenyouv1.websocketclient.toserverentity.ToServerEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
@Slf4j
public class AutoBettingTask {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private PredictionMapper predictionMapper;

    @Autowired
    private AutoPlayMapper autoPlayMapper;

    @Scheduled(cron = "* * * * * ?")
    public void autoBettingJobHandler() {
        //获取标记
        try {
            Object predicted = redisTemplate.opsForValue().get("predicted");
            Object time = redisTemplate.opsForValue().get("time");
            List<AutoUserEntity> autoUsers = autoPlayMapper.selectAllAutoUsers();
            for (AutoUserEntity autoUser : autoUsers) {
                if (autoUser.getIs_auto() == 0) {
                    //取map获取一下，如过存在则停止
                    BettingSocketClient bettingSocketClient = BettingSocketClient.WEBSOCKET_CLIENT_MAP.get(autoUser.getUser_id());
                    if (ObjectUtil.isNotNull(bettingSocketClient)) {
                        /**
                         * 停止,日志信息记录,写入数据库，停止成功！,修改is_auto
                         */
                        log.info("用户退出:{}", autoUser.getUser_id());
                        autoUser.setIs_auto(0);
                        autoPlayMapper.updateAutoUserIsAuto(autoUser);
                        bettingSocketClient.close();
                        //关闭,且删除该key
                        BettingSocketClient.WEBSOCKET_CLIENT_MAP.remove(autoUser.getUser_id());
                    }
                    continue;
                }
                if (autoUser.getIs_auto() == 1) {
                    //从WEBSOCKET_CLIENT_MAP取出，是否存在
                    BettingSocketClient bettingSocketClient;
                    bettingSocketClient = BettingSocketClient.WEBSOCKET_CLIENT_MAP.get(autoUser.getUser_id());
                    if (ObjectUtil.isNull(bettingSocketClient)) {
                        //为空则取创建,并且放入map中
                        bettingSocketClient = new BettingSocketClient(autoUser, autoPlayMapper, redisTemplate, predictionMapper);
                        BettingSocketClient.WEBSOCKET_CLIENT_MAP.put(autoUser.getUser_id(), bettingSocketClient);
                        bettingSocketClient.connect();
                    }
                    if (ObjectUtil.isNull(predicted)) {
                        //说明已经投入过，或者刚刚启动
                        continue;
                    }
                    //所有用户执行完清空标记,表示当前轮结束
                    if (ObjectUtil.isNotNull(time)) {
                        //倒计时
                        RoundInfo roundInfo = (RoundInfo) time;
                        int countDownInt = (int) ((roundInfo.getEndTime()) - (System.currentTimeMillis() / 1000));
                        if (countDownInt >= 10) {
                            //改所有
                            bettingSocketClient.setFlag(true);
                        }
                    }
                    //新的一期，没下注
                    bettingSocketClient.setBetted(false);
                }
            }
            /**
             * 当预测模块结束后，才进行下注，保证预测已经生成
             */
            redisTemplate.delete("predicted");
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }

    /**
     * 心跳检测
     */
    @Scheduled(cron = "0/5 * * * * ?")
    public synchronized void autoHeartJobHandler() {
        //已经启动了就跳过,进行心跳检测
        if (BettingSocketClient.WEBSOCKET_CLIENT_MAP.isEmpty()) {
            return;
        }
        ToServerEntity toServerEntity = new ToServerEntity();
        toServerEntity.setCode(ToServerCode.PING).setData("ping");
        try {
            BettingSocketClient.WEBSOCKET_CLIENT_MAP.entrySet().stream()
                    .distinct()
                    .forEach(bettingSocketClient -> {
                        bettingSocketClient.getValue().send(JSONUtil.toJsonStr(toServerEntity));
                    });
        } catch (Exception e) {
            log.error(e.getMessage());
        }

    }
}
